#include "common\GLWindow.h"

#include <gl\gl.h>
#include <gl\glu.h>


// default values
GL_Window::GL_Window()
{
	m_windowPosX=0;
	m_windowPosY=0;
	m_windowWidth=800;
	m_windowHeight=600;
	m_screenWidth=800;
	m_screenHeight=600;
	m_bitsPerPixel=16;
	m_isFullScreen=false;
	m_hWnd=0;
	m_hDC=0;
	m_hRC=0;
}

// create OpenGL window
bool GL_Window::create(const char *title, bool fullScreen, const char *className, HINSTANCE hInstance, LPVOID lpParam)
{  
	m_isFullScreen=fullScreen;
	PIXELFORMATDESCRIPTOR pfd={
		sizeof(PIXELFORMATDESCRIPTOR),
		1,
		PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,
		PFD_TYPE_RGBA,
		m_bitsPerPixel,
		0,0,0,0,0,0,0,0,0,0,0,0,0,
		16,		// 16bit z-buffer
		0,		// no stencil buffer
		0,
		PFD_MAIN_PLANE,
		0,0,0,0};
	DWORD windowStyle=WS_OVERLAPPEDWINDOW;
	DWORD windowExtendedStyle=WS_EX_APPWINDOW;
	if(m_isFullScreen)
	{
		if(changeScreenResolution()==false)
		{
			MessageBox(HWND_DESKTOP,"Resolution change failed.","Error",MB_OK|MB_ICONEXCLAMATION);
			m_isFullScreen=false;
		}
		else
		{
			ShowCursor(false);
			windowStyle=WS_POPUP;
			windowExtendedStyle|=WS_EX_TOPMOST;
		}
	}
	RECT windowRect={getPosX(),getPosY(),getPosX()+getWidth(),getPosY()+getHeight()};
	if(m_isFullScreen==false)
	{
		AdjustWindowRectEx(&windowRect,windowStyle,0,windowExtendedStyle);
		if(windowRect.left<0)
		{
			windowRect.right-=windowRect.left;
			windowRect.left=0;
		}
		if(windowRect.top<0)
		{
			windowRect.bottom-=windowRect.top;
			windowRect.top=0;
		}
	}
	m_hWnd=CreateWindowEx(windowExtendedStyle,className,title,windowStyle,windowRect.left,windowRect.top,
		windowRect.right-windowRect.left,windowRect.bottom-windowRect.top,HWND_DESKTOP,0,hInstance,lpParam);
	while(m_hWnd!=0)
	{
		m_hDC=GetDC(m_hWnd);
		if(m_hDC==0) break;
		int pixelFormat = ChoosePixelFormat(m_hDC,&pfd);
		if(pixelFormat==0) break;
		if(SetPixelFormat(m_hDC,pixelFormat,&pfd)==false) break;
		m_hRC=wglCreateContext(m_hDC);
		if(m_hRC==0) break;
		if(wglMakeCurrent(m_hDC,m_hRC)==false) break;

    SelectObject(m_hDC, GetStockObject(SYSTEM_FONT));
    wglUseFontBitmaps(m_hDC, 0, 255, 1000);

		ShowWindow(m_hWnd,SW_NORMAL);
		reshapeGL();
		return true;
	}
	destroy();
	return false;
}

void GL_Window::destroy()
{
	if(m_hWnd!=0)
	{
		if(m_hDC!=0)
		{
			wglMakeCurrent(m_hDC,0);
			if(m_hRC!=0)
			{
				wglDeleteContext(m_hRC);
				m_hRC=0;
			}
			ReleaseDC(m_hWnd,m_hDC);
			m_hDC=0;
		}
		DestroyWindow(m_hWnd);
		m_hWnd=0;
	}
	if(m_isFullScreen)
	{
		ChangeDisplaySettings(NULL,0);
		ShowCursor(true);
	}
}

bool GL_Window::changeScreenResolution()
{
	DEVMODE dmScreenSettings;
	ZeroMemory(&dmScreenSettings,sizeof(DEVMODE));
	dmScreenSettings.dmSize=sizeof(DEVMODE);
	dmScreenSettings.dmPelsWidth=getWidth();
	dmScreenSettings.dmPelsHeight=getHeight();
	dmScreenSettings.dmBitsPerPel=m_bitsPerPixel;
	dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
	if(ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) return false;
	return true;
}

void GL_Window::reshapeGL()
{
	GLsizei width=getWidth();
	GLsizei height=getHeight();
	glViewport(0,0,width,height);	
	glMatrixMode(GL_PROJECTION);	
	glLoadIdentity();	
	gluPerspective(80.f,(GLfloat)width/(GLfloat)height,1.f,1000.f);	// FOV, aspect ratio, near-, far-clipping
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();	
}

void GL_Window::setPosX(int x)
{
	if(m_isFullScreen==false) m_windowPosX=x;
}

void GL_Window::setPosY(int y)
{
	if(m_isFullScreen==false) m_windowPosY=y;
}

int GL_Window::getPosX()
{
	if(m_isFullScreen==false) return m_windowPosX;
	return 0;
}

int GL_Window::getPosY()
{
	if(m_isFullScreen==false) return m_windowPosY;
	return 0;
}

void GL_Window::setWidth(int width)
{
	if(m_isFullScreen) m_screenWidth=width;
	else m_windowWidth=width;
}

void GL_Window::setHeight(int height)
{
	if(m_isFullScreen) m_screenHeight=height;
	else m_windowHeight=height;
}

int GL_Window::getWidth()
{
	if(m_isFullScreen) return m_screenWidth;
	else return m_windowWidth;
}

int GL_Window::getHeight()
{
	if(m_isFullScreen) return m_screenHeight;
	else return m_windowHeight;
}